/**
 * Bakalarska prace - Inteligentni budik
 * @package sleepCatcher
 * @file DataCollector.cpp
 * @author Jan Pesava - xpesav00
 * @email xpesav00@stud.fit.vutbr.cz
 * @date 24. 12. 2011
 */

#include <FSysSystemTime.h>

#include "SCDataCollector.h"
#include "SCDatabase.h"
#include "SCSettings.h"
#include "forms/FormCatchSleep.h"

using namespace Osp::Base::Utility;


SCDataCollector::SCDataCollector()
{
	//Not implemented
}

SCDataCollector::SCDataCollector(Form* pForm)
{
	this->pCurrentForm = pForm;
}

SCDataCollector::~SCDataCollector()
{
	if(this->pPartTimer != NULL)
		delete this->pPartTimer;

	if(this->pAlarmTimer != NULL)
		delete this->pAlarmTimer;
}

result
SCDataCollector::Construct()
{
	return E_SUCCESS;
}

void
SCDataCollector::SetSession(SCSession* pSession)
{
	this->pSession = pSession;
}

SCSession*
SCDataCollector::GetSession()
{
	return this->pSession;
}

void
SCDataCollector::SetAlarm(SCAlarm* pAlarm)
{
	this->pAlarm = pAlarm;
}

SCAlarm*
SCDataCollector::GetAlarm()
{
	return this->pAlarm;
}

void
SCDataCollector::SetPartTimer(Timer* pTimer)
{
	this->pPartTimer = pTimer;
}

Timer*
SCDataCollector::GetPartTimer()
{
	return this->pPartTimer;
}

void
SCDataCollector::SetAlarmTimer(Timer* pTimer)
{
	this->pAlarmTimer = pTimer;
}

Timer*
SCDataCollector::GetAlarmTimer()
{
	return this->pAlarmTimer;
}

void
SCDataCollector::AddSample(float xAxis, float yAxis, float zAxis)
{
	SCSample *pSample = new SCSample();

	pSample->SetType(SCSample::SLEEP_ACCELEROMETER_DATA);
	pSample->SetXaxis(xAxis);
	pSample->SetYaxis(yAxis);
	pSample->SetZaxis(zAxis);
	pSample->SetTime(this->GetCurrentDateTime());

	this->AddSample(pSample);
}

void
SCDataCollector::AddSample(SCSample* pSample)
{
	if(this->pSession != NULL)
	{
		this->pSession->AddSample(pSample);
	} else {
		delete pSample;
		AppLog("Neni nastaveno sezeni.");
	}
}

void
SCDataCollector::SetStartPartTimer()
{
	this->pPartTimer = new Timer();
	this->pPartTimer->Construct(*this);
	this->pPartTimer->Start(SCSettings::GetPartLengthTicks());
}

void
SCDataCollector::SetNextPartTimer()
{
	this->pSession->SetNextPart();
	this->pPartTimer->Start(SCSettings::GetPartLengthTicks());
}

void
SCDataCollector::SetStartAlarmTimer()
{
	if(this->pAlarm != NULL)
	{
		this->pAlarmTimer = new Timer();
		this->pAlarmTimer->Construct(*this);
		long long difference = SCSettings::GetAwakeTimeDifferenceTicks(); // 1800000; //maximalni dopredne zbuzeni.
		long long timeToAlarmRun;

		timeToAlarmRun = this->GetTimeDifference(this->GetCurrentDateTime().GetTimeOfDay(), this->pAlarm->GetTime().GetTimeOfDay());

		if(timeToAlarmRun - difference > 0)
		{
			this->pAlarmTimer->Start(timeToAlarmRun - difference);
		} else {
			this->pAlarmTimer->Start(1000);
		}
	}

	this->isEndAlarmTimer = false;
}

void
SCDataCollector::SetEndAlarmTimer()
{
	this->pAlarmTimer->Start(this->pSession->GetAwakeTimeIn());
}

void
SCDataCollector::ClearPartData()
{
	this->pSession->SetNextPart();
}

DateTime
SCDataCollector::GetCurrentDateTime()
{
	DateTime curentDateTime;
	Osp::System::SystemTime::GetCurrentTime(Osp::System::WALL_TIME ,curentDateTime);
	return curentDateTime;
}

void
SCDataCollector::OnTimerExpired(Timer &timer)
{
	if(&timer == this->pAlarmTimer)
	{
		//AppLog("AlarmTimer");
		if(this->pSession->IsAwakeTime() || this->isEndAlarmTimer)
		{
			//compute time to awake
			this->ComputeStats();
			((FormCatchSleep*) this->pCurrentForm)->StopCatch();
			this->AlarmRing();
		} else {
			//AppLog("SetEndAlarmTimer");
			this->isEndAlarmTimer = true;
			this->SetEndAlarmTimer();
		}
	} else if(&timer == this->pPartTimer) {
		//AppLog("partTimer");
		this->SetNextPartTimer();
	} else {
		AppLog("Neznamy timer");
	}

}

void
SCDataCollector::AlarmRing()
{
	this->pAlarm->Ring();
}

void
SCDataCollector::SetCurrentForm(Form* pForm)
{
	this->pCurrentForm = pForm;
}

Form*
SCDataCollector::GetCurrentForm()
{
	return this->pCurrentForm;
}

long long
SCDataCollector::GetTimeDifference(TimeSpan timeFrom, TimeSpan timeTo)
{
	if(timeFrom.GetTicks() < timeTo.GetTicks())
	{
		return timeTo.GetTicks() - timeFrom.GetTicks();
	} else {
		return TimeSpan::NUM_OF_TICKS_IN_DAY - timeFrom.GetTicks() + timeTo.GetTicks();
	}
}

void
SCDataCollector::ComputeStats()
{
	//method compute stats behind session
}

void
SCDataCollector::StartCatch()
{
	this->pSession = SCSession::GetSession();
	if(this->pAlarm != NULL)
	{
		this->pSession->SetEndDate(this->pAlarm->GetTime());
		this->pSession->SetActiveAlarm(this->pAlarm);
		this->pSession->SetType(SCSession::IDA_SESSION_TYPE_ANALYZE_AND_WAKEUP);
	} else {
		this->pSession->SetType(SCSession::IDA_SESSION_TYPE_JUST_ANALYZE);
	}

	//save Session
	this->pSession->Save();

	this->SetStartPartTimer();
	this->SetStartAlarmTimer();
}

void
SCDataCollector::StopCatch()
{
	if(this->pPartTimer != NULL)
	{
		delete this->pPartTimer;
		this->pPartTimer = NULL;
	}

	if(this->pAlarmTimer != NULL)
	{
		delete this->pAlarmTimer;
		this->pAlarmTimer = NULL;
	}

	if(this->pSession != NULL)
	{
		this->pSession->StopCatch();
	}
}
